//
//  DataManagement.m
//  reacticons
//
//  Created by Nong Nghia on 4/14/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
//  ----------------------------------------------------------
//
//  Item's field x:
//   - field1: "1" is already in Favorites folder, "0" is not in Favorites folder yet.
//   - field2: thumbnail of image from tumblr - photo_url_75
//   - field3: image with smallest size (with bound 100 x 100)
//   - field4: recently add - default is 19990102030405
//   - field5: recently used - default is 19990102030405
//   - field9: number of items in the folder
//   - field10: order number

#import "DataManagement.h"
#import "Photos.h"
#import "AppDelegate.h"
#import "Categories.h"
#import "TumblrDownloader.h"
#import "AppDelegate.h"
#import "TestFlight.h"
#import "Utilities.h"

#define TAGS_LIST @"LOL;OMG;WTF;IDK;DERP;AMUSED;NOT AMUSED;FACE PALM;INTERESTING;NO THANKS;GROSS;SAD;MAD;LOVE;DEAL;PROBLEMS;WHATS UP;RANDOM;COMIC FACES;MEME;WIN"

@interface DataManagement (internal)

- (void)generateCategoriesFirstTime;
- (void)generateCategories;
- (BOOL)configureCategoriesInfo;
- (BOOL)writeListTumblrItems:(NSMutableArray*)tumblrList ToEntity:(NSString*)entityName;
-(void)updateDatabaseWithListItems:(NSMutableArray*)itemsList;

@end

@implementation DataManagement

#pragma mark - Download From Tumblr

- (void)requestListItemFromTumblr{
    NSLog(@"DataManagement - requestListItemFromTumblr");
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getListItemFromTumblrSucceed:) name:@"kDownloadListFromTumblrSuccessNotification" object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getListItemFromTumblrFailed:) name:@"kDownloadListFromTumblrFailedNotification" object:nil];
    
    TumblrDownloader * tDownloader=[[TumblrDownloader alloc] init];
    [tDownloader downloadFromTumblrWithTag:@"ALL"];
}

- (void)getListItemFromTumblrSucceed:(NSNotification*)notification{
    
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"kDownloadListFromTumblrSuccessNotification" object:nil];
    
    NSMutableArray * itemsList=[notification object];
    
        NSLog(@"DataManager - getListItemFromTumblrSuccess:%d\n",[itemsList count]);
    int resultCount=[[[NSUserDefaults standardUserDefaults] objectForKey:@"NumberOfTumblrPosts"] intValue];
    if (resultCount!=itemsList.count) {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"kDownloadListFromTumblrFailedNotification" object:@"Toltal Posts received is Not Equal Posts on Server"];
        return;
        
    }
    
    else {
        NSString *initInfo=[[NSUserDefaults standardUserDefaults] objectForKey:@"INIT_DATA"];
        if (![initInfo isEqualToString:@"SUCCESS"]) {
            [self updateDatabaseWithListItems:itemsList];
        }
        else {
            NSInvocationOperation *invoOp=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(updateDatabaseWithListItems:) object:itemsList];
            [[(AppDelegate*)[[UIApplication sharedApplication]delegate] appQueue] addOperation:invoOp];            
        }
        
    }
    NSLog(@"DataManager - getListItemFromTumblrSuccess:Finish");
    
}

-(void)updateDatabaseWithListItems:(NSMutableArray*)itemsList{
    
    NSMutableArray *itemList=[[NSMutableArray alloc] init];
    
    for (NSDictionary *dic in itemsList) 
    {
        Items * item =[[Items alloc] init];
        [item setItemid:[NSString stringWithFormat:@"%@",[dic objectForKey:@"id"]]];
        [item setName:[(NSString *)[dic objectForKey:@"photo-url-1280"] lastPathComponent]];
        [item setImage:(NSString *)[dic objectForKey:@"photo-url-1280"] ];
        [item setCreated_date:[dic objectForKey:@"date-gmt"]];
        [item setModified_date:[dic objectForKey:@"time-stamp"]];
        
        [item setField2:[dic objectForKey:@"photo-url-75"]];
        [item setField3:[dic objectForKey:@"photo-url-250"]]; // @"photo-url-100" - old
        [item setField4:@"19990102030405"];
        [item setField5:@"19990102030405"];

        [item setParentid:[NSString stringWithFormat:@";%@;",[[dic objectForKey:@"tags"] componentsJoinedByString:@";"]]];
//        NSLog(@"%@",item.parentid);
        [item setType:@"item"];
        [itemList addObject:item];
        [item release];
    }
    
    [self writeListItems:itemList ToEntity:@"ManagedItems"];
    [self configureCategoriesInfo];
    NSLog(@"DataManager - UPDATE_DB_OK");
    [[NSNotificationCenter defaultCenter] postNotificationName:kUpdateDatabaseFinishNotification object:@"UPDATE_DB_OK"];
    
    

}

-(void)getListItemFromTumblrFailed:(NSNotification*)notification{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"kDownloadListFromTumblrFailedNotification" object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"kDownloadListFromTumblrSuccessNotification" object:nil];
    
}

#pragma mark - Get Data From Core Data

-(BOOL)configureCategoriesInfo{
    TFLog(@"DataManagement - configureCategoriesInfo");
    NSString * firstTimeStr=[[NSUserDefaults standardUserDefaults] objectForKey:@"FIRST_TIME"];
    if (firstTimeStr==nil||[firstTimeStr isEqualToString:@""]) {
        NSArray *categoryList=[TAGS_LIST componentsSeparatedByString:@";"];
        ManagedItems * managedItem = nil;
        for(int i=0;i<categoryList.count;i++){
            
            managedItem = [NSEntityDescription
                           insertNewObjectForEntityForName:@"ManagedItems"
                           inManagedObjectContext:[(AppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext]];
            [managedItem setItemid:[categoryList objectAtIndex:i]];
            [managedItem setName:[categoryList objectAtIndex:i]];
            [managedItem setParentid:@"-1"];
            [managedItem setField10:[NSNumber numberWithInt:i]];
            [managedItem setType:@"category"];
            managedItem=nil;
        }
        [(AppDelegate*)[[UIApplication sharedApplication]delegate] saveContext];
        [[NSUserDefaults standardUserDefaults] setValue:@"Done" forKey:@"FIRST_TIME"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
    
    NSLog(@"DataManagement - configureCategoriesInfo - success");

    return YES;
}

-(NSMutableArray*)getCategories{
    TFLog(@"DataManagement - getCategories");

    NSMutableArray *cList=[self readItemsFromEntity:@"ManagedItems" WithName:nil AndType:@"category" AndParentID:@"-1" orderBy:@"field10" ascending:YES];
//    NSLog(@"CLIST:%d",cList.count);
    
    
    NSMutableArray *result=[[NSMutableArray alloc] initWithObjects: nil];
    NSFetchRequest *fetchRequest = nil;
    NSEntityDescription *entity = nil;
    for (int i=0;i<cList.count;i++) {
        
        Items *item=[[Items alloc] init];
        
        entity = [NSEntityDescription entityForName:@"ManagedItems" 
                             inManagedObjectContext:[(AppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext]];
        
        fetchRequest = [[NSFetchRequest alloc] init];
        
        [fetchRequest setEntity:entity];
        
        fetchRequest.predicate=[NSPredicate predicateWithFormat:@"parentid CONTAINS %@", [NSString stringWithFormat:@";%@;",[[(ManagedItems*)[cList objectAtIndex:i] name] lowercaseString]]];
        
        // Edit the sort key as appropriate.
        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"created_date" ascending:NO];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
        //        [fetchRequest setFetchLimit:1];
        [fetchRequest setSortDescriptors:sortDescriptors];
        [fetchRequest setReturnsObjectsAsFaults:NO];
        NSError *error = nil;
        
        NSMutableArray *mutableFetchResults = [[[(AppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext] executeFetchRequest:fetchRequest error:&error] mutableCopy];
        
        
        item.name= [(ManagedItems*)[cList objectAtIndex:i] name];
        item.field10=[(ManagedItems*)[cList objectAtIndex:i] field10];
        
        if (mutableFetchResults!=nil) {
            if (mutableFetchResults.count>0) {
                item.image  = [(ManagedItems*)[mutableFetchResults objectAtIndex:0] image];
                item.field1 = [(ManagedItems*)[mutableFetchResults objectAtIndex:0] field1];
                item.field2 = [(ManagedItems*)[mutableFetchResults objectAtIndex:0] field2];
                item.field3 = [(ManagedItems*)[mutableFetchResults objectAtIndex:0] field3];
                item.field9 = [NSString stringWithFormat:@"%d",[mutableFetchResults count]];
            }
            else {
                item.image  = @"";
                item.field1 = @"";
                item.field2 = @"";
                item.field3 = @"";
                item.field9 = @"0";
                
            }
        }
        [result addObject:item];
        item=nil;
        fetchRequest=nil;
    }
    
    return result;
}


- (Items*)readAnItemFromManagedItem:(ManagedItems*)managedItem
{
    Items * item = [[Items alloc] init];
    
    item.itemid = managedItem.itemid;
    item.name = managedItem.name;
    item.type = managedItem.type;
    item.short_description = managedItem.short_description;
    item.descriptions = managedItem.descriptions;
    item.created_date = managedItem.created_date;
    item.modified_date = managedItem.modified_date;
    item.parentid = managedItem.parentid;
    item.image = managedItem.image;
    item.version = managedItem.version;
    item.deleted = managedItem.deleted;
    item.field1 = managedItem.field1;
    item.field2 = managedItem.field2;
    item.field3 = managedItem.field3;
    item.field4 = managedItem.field4;
    item.field5 = managedItem.field5;
    item.field6 = managedItem.field6;
    item.field7 = managedItem.field7;
    item.field8 = managedItem.field8;
    item.field9 = managedItem.field9;
    item.field10 = managedItem.field10;
    
    return [item autorelease];
}

- (NSMutableArray*)readAllItemsFromEntity:(NSString*)entityName
{
    return [self readItemsFromEntity:entityName WithName:nil AndType:nil AndParentID:nil];
}

- (NSMutableArray*)readItemsFromEntity:(NSString*)entityName WithType:(NSString*)type
{
    return [self readItemsFromEntity:entityName WithName:nil AndType:type AndParentID:nil];
}

- (NSMutableArray*)readItemsFromEntity:(NSString*)entityName WithType:(NSString*)type AndParentID:(NSString*)parentID
{
    return [self readItemsFromEntity:entityName WithName:nil AndType:type AndParentID:parentID];
}

- (NSMutableArray*)readItemsFromEntity:(NSString*)entityName WithName:(NSString*)name AndType:(NSString*)type AndParentID:(NSString*)parentID
{
    return [self readItemsFromEntity:entityName WithName:name AndType:type AndParentID:parentID orderBy:@"created_date" ascending:NO];
}

- (NSMutableArray*)readItemsFromEntity:(NSString*)entityName WithName:(NSString*)name AndType:(NSString*)type AndParentID:(NSString*)parentID orderBy:(NSString*)orderField ascending:(BOOL)ascending
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityName 
                                              inManagedObjectContext:[(AppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext]];
    [fetchRequest setEntity:entity];
    NSString * predicateString = @"";
    if (![name isEqualToString:@""] && name != nil) {
        predicateString = [NSString stringWithFormat:@"%@ AND name = '%@'", predicateString, name];
    }
    
    if (![type isEqualToString:@""] && type != nil) {
        predicateString = [NSString stringWithFormat:@"%@ AND type = '%@'", predicateString, type];
    }
    
    if (![parentID isEqualToString:@""] && parentID != nil) {
        predicateString = [NSString stringWithFormat:@"%@ AND parentid CONTAINS '%@'", predicateString, parentID];
    }
    
    if ([predicateString rangeOfString:@" AND "].location == 0) {
        predicateString = [predicateString substringFromIndex:5];
    }
    
    //    NSLog(@"predicateString = %@", predicateString);
    if (![predicateString isEqualToString:@""]) {
        [fetchRequest setPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"%@", predicateString]]];
    }
    
    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:orderField ascending:ascending];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    
    [fetchRequest setSortDescriptors:sortDescriptors];
//    NSLog(@"DataManager - fetchRequest: %@",fetchRequest);
    
    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
	NSError *error = nil;
    [fetchRequest setReturnsObjectsAsFaults:NO];
	NSMutableArray *mutableFetchResults = [[[(AppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext] executeFetchRequest:fetchRequest error:&error] mutableCopy];
    
    NSMutableArray * itemsArr = [[NSMutableArray alloc] init];
    
	if (mutableFetchResults != nil) {
        for (int i = 0; i < mutableFetchResults.count; i++) {
            [itemsArr addObject:[self readAnItemFromManagedItem:[mutableFetchResults objectAtIndex:i]]];
        }
	}
    
    [fetchRequest release];
    [sortDescriptor release];
    [sortDescriptors release];
//    NSLog(@"%@",itemsArr);
	return [itemsArr autorelease];
}

- (NSMutableArray*)readRecentlyItemsWithType:(NSString*)recentlyItemType

{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"ManagedItems" 
                                              inManagedObjectContext:[(AppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext]];
    [fetchRequest setEntity:entity];
    
    
    //    NSLog(@"predicateString = %@", predicateString);
    
    
    NSSortDescriptor *sortDescriptor =nil;
    // Edit the sort key as appropriate.
    if ([recentlyItemType isEqualToString:@"recentlyAdded"]) {
        
        NSDate *now=[NSDate date];
        NSDate *mileStone=[now dateByAddingTimeInterval:- 7*24*60*60];
        NSDateFormatter *dFormat=[[NSDateFormatter alloc] init];
        [dFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss +0000"];
        NSString *time= [NSString stringWithFormat:@"%@",[dFormat stringFromDate:mileStone]];
        [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"type = %@ AND created_date > %@",@"item",time]];
        sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"created_date" ascending:NO];
        
    }
    else {
        [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"type = %@ AND field5 > %@",@"item",@"19990102030405"]];
        sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"field5" ascending:NO];
        [fetchRequest setFetchLimit:100];
        
    }
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    
    [fetchRequest setSortDescriptors:sortDescriptors];
//    NSLog(@"DataManager - fetchRequest: %@",fetchRequest);
    
    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
	NSError *error = nil;
    [fetchRequest setReturnsObjectsAsFaults:NO];
	NSMutableArray *mutableFetchResults = [[[(AppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext] executeFetchRequest:fetchRequest error:&error] mutableCopy];
    
    NSMutableArray * itemsArr = [[NSMutableArray alloc] init];
    
	if (mutableFetchResults != nil) {
        for (int i = 0; i < mutableFetchResults.count; i++) {
            [itemsArr addObject:[self readAnItemFromManagedItem:[mutableFetchResults objectAtIndex:i]]];
        }
	}
    else {
        NSLog(@"list nil");
        return nil;
    }
    NSLog(@"itemarr:%d",itemsArr.count);
    
    [fetchRequest release];
    [sortDescriptor release];
    [sortDescriptors release];
    //    NSLog(@"%@",itemsArr);
	return [itemsArr autorelease];
}

#pragma mark - Write Data To Core Data

- (BOOL)writeAnItem:(Items*)item ToEntity:(NSString*)entityName Immediatly:(BOOL)now
{
    NSError * error=nil;
    ManagedItems * managedItem = nil;
    managedItem = [NSEntityDescription
                   insertNewObjectForEntityForName:entityName
                   inManagedObjectContext:[(AppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext]];
    
    [managedItem setItemid:item.itemid];
    [managedItem setName:item.name];
    [managedItem setType:item.type];
    [managedItem setField1:item.field1];
    [managedItem setField2:item.field2];
    [managedItem setField3:item.field3];
    [managedItem setField4:item.field4];
    [managedItem setField5:item.field5];
    [managedItem setField6:item.field6];
    [managedItem setField7:item.field7];
    [managedItem setField8:item.field8];
    [managedItem setField9:item.field9];
    [managedItem setField10:item.field10];
    
    if (![item.short_description isEqual:[NSNull null]]) {
        [managedItem setShort_description:item.short_description];
    }
    else
    {
        [managedItem setShort_description:@""];
    }
    if (![item.descriptions isEqual:[NSNull null]]) {
        [managedItem setDescriptions:item.descriptions];
    }
    else
    {
        [managedItem setDescriptions:@""];
    }
    [managedItem setDeleted:item.deleted];
    
    if (![item.parentid isEqual:[NSNull null]]) {
        [managedItem setParentid:item.parentid];
    }
    else
    {
        [managedItem setParentid:@""];
    }
    
    if (![item.image isEqual:[NSNull null]]) {
        [managedItem setImage:item.image];
    }
    else
    {
        [managedItem setImage:@""];
    }
    [managedItem setVersion:item.version];
    [managedItem setCreated_date:item.created_date];
    [managedItem setModified_date:item.modified_date];
    
    if (!now) {
//        NSLog(@"DataManagement - writeAnItem:%@",item.name);

        return YES;
    }
    if (![[(AppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext] save:&error]) 
    {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        return NO;
    }
    return YES;
}

- (BOOL)updateAnItem:(Items*)item ToManagedItem:(ManagedItems*)managedItem Immediatly:(BOOL)now
{
    NSError * error;
    
    [managedItem setValue:item.itemid forKey:@"itemid"];
    [managedItem setValue:item.name forKey:@"name"];
    [managedItem setValue:item.type forKey:@"type"];
    [managedItem setValue:item.field1 forKey:@"field1"];
    [managedItem setValue:item.field2 forKey:@"field2"];
    [managedItem setValue:item.field3 forKey:@"field3"];
    [managedItem setValue:item.field4 forKey:@"field4"];
    [managedItem setValue:item.field5 forKey:@"field5"];
    [managedItem setValue:item.field6 forKey:@"field6"];
    [managedItem setValue:item.field7 forKey:@"field7"];
    [managedItem setValue:item.field8 forKey:@"field8"];
    [managedItem setValue:item.field9 forKey:@"field9"];
    [managedItem setValue:item.field10 forKey:@"field10"];
    
    if ([item.short_description isEqual:[NSNull null]])
        [managedItem setValue:@"" forKey:@"short_description"];
    else
        [managedItem setValue:item.short_description forKey:@"short_description"];
    
    if ([item.descriptions isEqual:[NSNull null]])
        [managedItem setValue:@"" forKey:@"descriptions"];
    else
        [managedItem setValue:item.descriptions forKey:@"descriptions"];
    
    if ([item.parentid isEqual:[NSNull null]])
        [managedItem setValue:@"" forKey:@"parentid"];
    else
        [managedItem setValue:item.parentid forKey:@"parentid"];
    
    if ([item.image isEqual:[NSNull null]])
        [managedItem setValue:@"" forKey:@"image"];
    else
        [managedItem setValue:item.image forKey:@"image"];
    
    [managedItem setValue:item.created_date forKey:@"created_date"];
    [managedItem setValue:item.modified_date forKey:@"modified_date"];
    [managedItem setValue:item.version forKey:@"version"];
    [managedItem setValue:item.deleted forKey:@"deleted"];
    
    if (!now) {
//        NSLog(@"DataManagement - updateAnItem:%@",item.name);
        return YES;
    }
    if (![[(AppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext] save:&error]) 
    {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        return NO;
    }
    return YES;
}

- (BOOL)updateAnItem:(Items*)item inEntityWithName:(NSString *)entityName
{
    NSError *error = nil;
    NSManagedObjectContext * context = [(AppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext];
    //This is your NSManagedObject subclass
    ManagedItems * aManagedItem = nil;
    
    //Set up to get the thing you want to update
    NSFetchRequest * request = [[NSFetchRequest alloc] init];
    [request setEntity:[NSEntityDescription entityForName:entityName 
                                   inManagedObjectContext:context]];
    [request setPredicate:[NSPredicate predicateWithFormat:@"itemid=%@",item.itemid]];
    
    //Ask for it
    aManagedItem = [[context executeFetchRequest:request error:&error] lastObject];
    [request release];
    
    if (error) {
        //Handle any errors
        return NO;
    }
    
    if (!aManagedItem) {
        //Nothing there to update
        return NO;
    }
    
    //Update the object
    [self updateAnItem:item ToManagedItem:aManagedItem Immediatly:YES];
    return YES;
}

- (BOOL)writeListItems:(NSMutableArray*)list ToEntity:(NSString*)entityName
{
    [list retain];
    [(AppDelegate*)[[UIApplication sharedApplication] delegate] saveContext];
    
    for (int i=0;i<[list count];i++) 
    {
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        
        NSEntityDescription *ent = [NSEntityDescription entityForName:entityName inManagedObjectContext:[(AppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext]];
        [fetchRequest setEntity:ent];
        
        // narrow the fetch to these two properties
        //        fetchRequest.propertiesToFetch = [NSArray arrayWithObjects:@"itemid", @"type", nil];
        
        NSError *error = NULL;
        Items *item = nil;
        item = [list objectAtIndex:i];
        
        fetchRequest.predicate = [NSPredicate predicateWithFormat:@"itemid =[cd] %@ AND type =[cd] %@", item.itemid, item.type];
        
        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"itemid" ascending:NO];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
        [fetchRequest setSortDescriptors:sortDescriptors];
        
        NSMutableArray *fetchedItems = [[[(AppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext] executeFetchRequest:fetchRequest error:nil] mutableCopy];
        if (error) {
            NSLog(@"err:%@",[error description]);
        }
        if (fetchedItems) {
            if ([fetchedItems count] == 0)
            {
//                NSLog(@"insert:%d",i);
                // Insert
                if (![self writeAnItem:item ToEntity:entityName Immediatly:NO]){
                    return NO;
                }
            }
            else {
                // Update
//            if(![self updateAnItem:item ToManagedItem:[fetchedItems objectAtIndex:0] Immediatly:NO])
                return NO;
            }  
        }
        fetchRequest=nil;
        
    }
    [(AppDelegate*)[[UIApplication sharedApplication] delegate] saveContext];
    return YES;
}


- (BOOL)writeListTumblrItems:(NSMutableArray*)tumblrList ToEntity:(NSString*)entityName
{
    [tumblrList retain];
    [(AppDelegate*)[[UIApplication sharedApplication] delegate] saveContext];
    
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    
    NSEntityDescription *ent = [NSEntityDescription entityForName:entityName inManagedObjectContext:[(AppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext]];
    [fetchRequest setEntity:ent];
    
    NSError *error = NULL;
    
    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"type =[cd] %@", @"item"];
    
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"created_date" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    
    [fetchRequest setSortDescriptors:sortDescriptors];
    [fetchRequest setReturnsObjectsAsFaults:NO];
    
    NSMutableArray *fetchedItems = [[[(AppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext] executeFetchRequest:fetchRequest error:nil] mutableCopy];
    if (error) {
        NSLog(@"err:%@",[error description]);
        return NO;
    }
    NSMutableArray *dbList=[[NSMutableArray alloc] init];
    
    
    
    if (fetchedItems != nil) {
        NSLog(@"FETCH NOT NIL");
       
        if (fetchedItems.count==0) {
            for (Items * item in tumblrList) {
                NSLog(@"add:%@",item.created_date);
                if (![self writeAnItem:item ToEntity:entityName Immediatly:NO]){
                    NSLog(@"ADD FAILED:%@",item.created_date);
                }
            }
        }
        else {
            for (int i = 0; i <fetchedItems.count ; i++) {
                [dbList addObject:[self readAnItemFromManagedItem:[fetchedItems objectAtIndex:i]]];
            }
            NSUInteger tumblrIndex=0,dbIndex=0;
            NSDateFormatter *dateFormater=[[NSDateFormatter alloc] init];
            [dateFormater setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
            while (tumblrIndex< tumblrList.count && dbIndex < dbList.count) {
                
                if (tumblrIndex>=tumblrList.count) {
                    for (int i=dbIndex;i<dbList.count;i++) {
                        //delete
                        NSLog(@"DELETEDB:%d",i);
                    }
                    break;
                }
                
                if (dbIndex>=dbList.count) {
                    for (int i=tumblrIndex;i<tumblrList.count;i++) {
                        //delete
                        NSLog(@"ADD:%d",i);
                    }
                    break;
                }
                
                Items * tumblrItem=[tumblrList objectAtIndex:tumblrIndex];
                Items * dbItem=[dbList objectAtIndex:dbIndex];
                NSDate *tumblrTime=[dateFormater dateFromString:[tumblrItem.created_date substringToIndex:19]];

                NSDate *dbTime=[dateFormater dateFromString:[dbItem.created_date substringToIndex:19]];

//                NSLog(@"COMPARE: %@|%@",tumblrTime,dbTime);
                if ([tumblrTime compare:dbTime]==NSOrderedAscending) {
                    //add 2 db
                    tumblrIndex++;
                    if (![self writeAnItem:tumblrItem ToEntity:entityName Immediatly:NO]){
                        TFLog(@"ADD FAILED:%@",tumblrItem.created_date);
                    }
                    else {
                        NSLog(@"ADD SUCCESS:%@",tumblrItem.created_date);

                    }
                }
                else {
                    if ([tumblrTime compare:dbTime]==NSOrderedSame) {
                        tumblrIndex++;
                        dbIndex++;
//                        NSLog(@"UPDATE DB:%@",tumblrItem.created_date);
                        
                        // update db
                        
                    }
                    else {
                        // delete from db
                        NSLog(@"DELETEDB:%@",dbItem.created_date);
                        dbIndex++;
                    }
                }
            }
        }
         

	}
    else {
        NSLog(@"FETCH NIL");   
    }
    
    
    
    [(AppDelegate*)[[UIApplication sharedApplication] delegate] saveContext];
//    [TestFlight passCheckpoint:@"DataManager - write to list - quit"];
    return YES;
}

#pragma mark - Favorite

-(NSMutableArray*)getFavoriteList{
    NSLog(@"DataManagement - getFavoriteList");
    NSFileManager *fm=[[NSFileManager alloc] init];
    NSString *documentPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *favoritePath=[documentPath stringByAppendingPathComponent:@"Favorites"];
    if (![fm fileExistsAtPath:favoritePath]) {
        [fm createDirectoryAtPath:favoritePath withIntermediateDirectories:YES attributes:nil error:nil];
    }
    NSString *fThumbnail=[documentPath stringByAppendingPathComponent:@"FThumbnail"];
    
    if (![fm fileExistsAtPath:fThumbnail]) {
        [fm createDirectoryAtPath:fThumbnail withIntermediateDirectories:YES attributes:nil error:nil];
    }
    
    NSArray *fileList=[fm contentsOfDirectoryAtPath:favoritePath error:nil];

//    NSArray *tList=[fm contentsOfDirectoryAtPath:fThumbnail error:nil];

    NSMutableArray *result=[[NSMutableArray alloc] init];
    for(int i=fileList.count-1;i>=0;i--){
        
        if (![fm fileExistsAtPath:[fThumbnail stringByAppendingPathComponent:[fileList objectAtIndex:i]]]) {
            NSLog(@"create thumbnail:%@",[fileList objectAtIndex:i]);
            [fm createFileAtPath:[fThumbnail stringByAppendingPathComponent:[fileList objectAtIndex:i]] 
                        contents: UIImageJPEGRepresentation([Utilities resizedImage:[UIImage imageWithContentsOfFile:[favoritePath stringByAppendingPathComponent:[fileList objectAtIndex:i]]] 
                                                                           withRect:CGRectMake(0, 0, 150, 150)], 
                                                            1.0)
                      attributes:nil];
        }
        
        Items *item=[[Items alloc] init];
        [item setName:[fileList objectAtIndex:i]];
        [item setItemid:[NSString stringWithFormat:@"%@",[fileList objectAtIndex:i]]];
        [item setImage:[NSString stringWithFormat:@"%@",[NSURL fileURLWithPath:[fThumbnail stringByAppendingPathComponent:[fileList objectAtIndex:i]] ]]];
        [result addObject:item];
        item=nil;
        
        
    }
    return [result autorelease];
}

-(NSMutableArray*)getMemeList{
    NSLog(@"DataManagement - getMemeList");
    NSFileManager *fm=[[NSFileManager alloc] init];
    NSString *documentPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *favoritePath=[documentPath stringByAppendingPathComponent:@"Meme"];
    if (![fm fileExistsAtPath:favoritePath]) {
        [fm createDirectoryAtPath:favoritePath withIntermediateDirectories:YES attributes:nil error:nil];
    }
    NSString *fThumbnail=[documentPath stringByAppendingPathComponent:@"MemeThumbnail"];
    
    if (![fm fileExistsAtPath:fThumbnail]) {
        [fm createDirectoryAtPath:fThumbnail withIntermediateDirectories:YES attributes:nil error:nil];
    }
    
    NSArray *fileList=[fm contentsOfDirectoryAtPath:favoritePath error:nil];
    
    //    NSArray *tList=[fm contentsOfDirectoryAtPath:fThumbnail error:nil];
    
    NSMutableArray *result=[[NSMutableArray alloc] init];
    for(int i=fileList.count-1;i>=0;i--){
        
        if (![fm fileExistsAtPath:[fThumbnail stringByAppendingPathComponent:[fileList objectAtIndex:i]]]) {
            NSLog(@"create thumbnail:%@",[fileList objectAtIndex:i]);
            [fm createFileAtPath:[fThumbnail stringByAppendingPathComponent:[fileList objectAtIndex:i]] 
                        contents: UIImageJPEGRepresentation([Utilities resizedImage:[UIImage imageWithContentsOfFile:[favoritePath stringByAppendingPathComponent:[fileList objectAtIndex:i]]] 
                                                                           withRect:CGRectMake(0, 0, 150, 150)],1.0)
                      attributes:nil];
        }
        
        Items *item=[[Items alloc] init];
        [item setName:[fileList objectAtIndex:i]];
        [item setItemid:[NSString stringWithFormat:@"%@",[fileList objectAtIndex:i]]];
        [item setImage:[NSString stringWithFormat:@"%@",[NSURL fileURLWithPath:[fThumbnail stringByAppendingPathComponent:[fileList objectAtIndex:i]] ]]];
        [result addObject:item];
        item=nil;
        
        
    }
    return [result autorelease];
}

@end
